#include "test.h"
#include "test_vector.h"



bool test_vec2()
{
	Vec2 v1;
	Vec2 v2(2.0,1.0);
	Vec2 v3(v2);
	Vec2 v4=-v2;
	Vec2 v5(1.0,1.0);

	// creation check
	ASSERT_EQUALS(v1.x, 0);
	ASSERT_EQUALS(v1.y, 0);
	ASSERT_EQUALS(v2.x, 2.0);
	ASSERT_EQUALS(v2.y, 1.0);
	ASSERT_EQUALS(v3.x, 2.0);
	ASSERT_EQUALS(v3.y, 1.0);
	ASSERT_TRUE(v3 != v2);
	ASSERT_EQUALS(v4.x, -2.0);
	ASSERT_EQUALS(v4.y, -1.0);
	ASSERT_EQUALS(v5.x, 1.0);
	ASSERT_EQUALS(v5.y ,1.0);

	// arithmetic check
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((v4*2).x, -4.0);
	ASSERT_EQUALS((v4*2).y, -2.0);
	ASSERT_EQUALS((v4+v4).x, -4.0);
	ASSERT_EQUALS((v4+v4).y, -2.0);
	ASSERT_EQUALS((v4-v4).x, 0.0);
	ASSERT_EQUALS((v4-v4).y, 0.0);
	ASSERT_EQUALS((v2*v4).x, -4.0);
	ASSERT_EQUALS((v2*v4).y, -1.0);
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);

	v3+=v2;
	ASSERT_EQUALS(v3.x, 4.0);
	ASSERT_EQUALS(v3.y, 2.0);

	v5+=v3;
	ASSERT_EQUALS(v5.x, 5.0);
	ASSERT_EQUALS(v5.y, 3.0);

	v5-=v3;
	ASSERT_EQUALS(v5.x, 1.0);
	ASSERT_EQUALS(v5.y, 1.0);

	v3/=2;
	ASSERT_EQUALS(v3.x, 2.0);
	ASSERT_EQUALS(v3.y, 1.0);

	v3*=3;
	ASSERT_EQUALS(v3.x, 6.0);
	ASSERT_EQUALS(v3.y, 3.0);

	v3*=v5;
	ASSERT_EQUALS(v3.x, 6.0);
	ASSERT_EQUALS(v3.y, 3.0);

	Vec2 vec6(2.0,0.0);
	v3-=vec6;

	ASSERT_EQUALS(v3.dot(v3), 25.0);
	ASSERT_EQUALS(v3.length(), 5.0);
	
	v3.normalize();
	ASSERT_EQUALS(v3.x, 4.0f/5);
	ASSERT_EQUALS(v3.y, 3.0f/5);
	ASSERT_EQUALS(v3.length(), 1);

	return true;
}

bool test_vec3()
{
	Vec3 v1;
	Vec3 v2(2.0,1.0,1.0);
	Vec3 v3(v2);
	Vec3 v4=-v2;
	Vec3 v5(1.0,1.0,1.0);
	Vec3 vec6(2.0,0.0,3.0);
	Vec2 vec22(2.0,2.0);

	//creation check
	ASSERT_EQUALS(v1.x, 0);
	ASSERT_EQUALS(v1.y, 0);
	ASSERT_EQUALS(v1.z, 0);
	ASSERT_EQUALS(v2.x, 2.0);
	ASSERT_EQUALS(v2.y, 1.0);
	ASSERT_EQUALS(v2.z, 1.0);
	ASSERT_EQUALS(v3.x, 2.0);
	ASSERT_EQUALS(v3.y, 1.0);
	ASSERT_EQUALS(v3.z, 1.0);
	ASSERT_TRUE(v3 != v2);
	ASSERT_EQUALS(v4.x, -2.0);	
	ASSERT_EQUALS(v4.y, -1.0);
	ASSERT_EQUALS(v4.z, -1.0);
	ASSERT_EQUALS(v5.x, 1.0);
	ASSERT_EQUALS(v5.y, 1.0);
	ASSERT_EQUALS(v5.z, 1.0);

	// arithmetic check:
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((v4*2).x, -4.0);
	ASSERT_EQUALS((v4*2).y, -2.0);
	ASSERT_EQUALS((v4+v4).x, -4.0);
	ASSERT_EQUALS((v4+v4).y, -2.0);
	ASSERT_EQUALS((v4-v4).x, 0.0);
	ASSERT_EQUALS((v4-v4).y, 0.0);
	ASSERT_EQUALS((v2*v4).x, -4.0);
	ASSERT_EQUALS((v2*v4).y, -1.0);

	ASSERT_EQUALS((2*v4).z, -2.0);
	ASSERT_EQUALS((v4*2).z, -2.0);
	ASSERT_EQUALS((v4+v4).z, -2.0);
	ASSERT_EQUALS((v4-v4).z, 0.0);
	ASSERT_EQUALS((v2*v4).z, -1.0);

	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);

	ASSERT_EQUALS((2*v4).z, -2.0);
	ASSERT_EQUALS((2*v4).z, -2.0);
	ASSERT_EQUALS((2*v4).z, -2.0);

	v3+=v2;
	ASSERT_EQUALS(v3.x, 4.0);
	ASSERT_EQUALS(v3.y, 2.0);
	ASSERT_EQUALS(v3.z, 2.0);

	v5+=v3;
	ASSERT_EQUALS(v5.x, 5.0);
	ASSERT_EQUALS(v5.y, 3.0);
	ASSERT_EQUALS(v5.z, 3.0);

	v5-=v3;
	ASSERT_EQUALS(v5.x, 1.0);
	ASSERT_EQUALS(v5.y, 1.0);
	ASSERT_EQUALS(v5.z, 1.0);


	v3/=2;
	ASSERT_EQUALS(v3.x, 2.0);
	ASSERT_EQUALS(v3.y, 1.0);
	ASSERT_EQUALS(v3.z, 1.0);

	v3*=3;
	ASSERT_EQUALS(v3.x, 6.0);
	ASSERT_EQUALS(v3.y, 3.0);
	ASSERT_EQUALS(v3.z, 3.0);

	v3*=v5;
	ASSERT_EQUALS(v3.x, 6.0);
	ASSERT_EQUALS(v3.y, 3.0);
	ASSERT_EQUALS(v3.z, 3.0);

	v3-=vec6;
	ASSERT_EQUALS(v3.dot(v3), 25.0);
	ASSERT_EQUALS(v3.length(), 5.0);

	v3.normalize();
	ASSERT_EQUALS(v3.x, 4.0f/5);
	ASSERT_EQUALS(v3.y, 3.0f/5);
	ASSERT_EQUALS(v3.z, 0);
	ASSERT_EQUALS(v3.length(), 1);

	return true;
}

bool test_vec4()
{
	Vec4 v1;
	Vec4 v2(2.0,1.0,2.0,1.0);
	Vec4 v3(v2);
	Vec4 v4=-v2;
	Vec4 v5(1.0,1.0,1.0,1.0);
	Vec4 vec6(2.0,0.0,3.0,3.0);

	//creation check
	ASSERT_EQUALS(v1.x, 0);
	ASSERT_EQUALS(v1.y, 0);
	ASSERT_EQUALS(v2.x, 2.0);
	ASSERT_EQUALS(v2.y, 1.0);
	ASSERT_EQUALS(v3.x, 2.0);
	ASSERT_EQUALS(v3.y, 1.0);
	ASSERT_TRUE(v3!=v2);
	ASSERT_EQUALS(v4.x, -2.0);	
	ASSERT_EQUALS(v4.y, -1.0);
	ASSERT_EQUALS(v5.x, 1.0);
	ASSERT_EQUALS(v5.y, 1.0);

	ASSERT_EQUALS(v1.z, 0);
	ASSERT_EQUALS(v1.w, 0);
	ASSERT_EQUALS(v2.z, 2.0);
	ASSERT_EQUALS(v2.w, 1.0);
	ASSERT_EQUALS(v3.z, 2.0);
	ASSERT_EQUALS(v3.w, 1.0);
	ASSERT_TRUE(v3!=v2);
	ASSERT_EQUALS(v4.z, -2.0);	
	ASSERT_EQUALS(v4.w, -1.0);
	ASSERT_EQUALS(v5.z, 1.0);
	ASSERT_EQUALS(v5.w, 1.0);

	//arithmetic check
	ASSERT_EQUALS((2*v4).x, -4.0);
	ASSERT_EQUALS((2*v4).y, -2.0);
	ASSERT_EQUALS((v4*2).x, -4.0);
	ASSERT_EQUALS((v4*2).y, -2.0);
	ASSERT_EQUALS((v4+v4).x, -4.0);
	ASSERT_EQUALS((v4+v4).y, -2.0);
	ASSERT_EQUALS((v4-v4).x, 0.0);
	ASSERT_EQUALS((v4-v4).y, 0.0);
	ASSERT_EQUALS((v2*v4).x, -4.0);
	ASSERT_EQUALS((v2*v4).y, -1.0);
	ASSERT_EQUALS((2*v4).z, -4.0);
	ASSERT_EQUALS((2*v4).w, -2.0);
	ASSERT_EQUALS((v4*2).z, -4.0);
	ASSERT_EQUALS((v4*2).w, -2.0);
	ASSERT_EQUALS((v4+v4).z, -4.0);
	ASSERT_EQUALS((v4+v4).w, -2.0);
	ASSERT_EQUALS((v4-v4).z, 0.0);
	ASSERT_EQUALS((v4-v4).w, 0.0);
	ASSERT_EQUALS((v2*v4).z, -4.0);
	ASSERT_EQUALS((v2*v4).w, -1.0);

	v3+=v2;
	ASSERT_EQUALS(v3.x, 4.0);
	ASSERT_EQUALS(v3.y, 2.0);
	ASSERT_EQUALS(v3.z, 4.0);
	ASSERT_EQUALS(v3.w, 2.0);

	v5+=v3;
	ASSERT_EQUALS(v5.x, 5.0);
	ASSERT_EQUALS(v5.y, 3.0);
	ASSERT_EQUALS(v5.z, 5.0);
	ASSERT_EQUALS(v5.w, 3.0);

	v5-=v3;
	ASSERT_EQUALS(v5.x, 1.0);
	ASSERT_EQUALS(v5.y, 1.0);
	ASSERT_EQUALS(v5.z, 1.0);
	ASSERT_EQUALS(v5.w, 1.0);

	v3/=2;
	ASSERT_EQUALS(v3.x, 2.0);
	ASSERT_EQUALS(v3.y, 1.0);
	ASSERT_EQUALS(v3.z, 2.0);
	ASSERT_EQUALS(v3.w, 1.0);

	v3*=3;
	ASSERT_EQUALS(v3.x, 6.0);
	ASSERT_EQUALS(v3.y, 3.0);
	ASSERT_EQUALS(v3.z, 6.0);
	ASSERT_EQUALS(v3.w, 3.0);

	v3*=v5;
	ASSERT_EQUALS(v3.x, 6.0);
	ASSERT_EQUALS(v3.y, 3.0);
	ASSERT_EQUALS(v3.z, 6.0);
	ASSERT_EQUALS(v3.w, 3.0);

	v3-=vec6;

	ASSERT_EQUALS(v3.dot(v3), 34);
	ASSERT_DOUBLE_EQAULS(v3.length(), std::sqrt(34.0));

	float len = v3.length();
	v3.normalize();

	ASSERT_DOUBLE_EQAULS(v3.x, 4.0f/len);
	ASSERT_DOUBLE_EQAULS(v3.y, 3.0f/len);
	ASSERT_DOUBLE_EQAULS(v3.z, 3.0f/len);
	ASSERT_DOUBLE_EQAULS(v3.w, 0.0f/len);
	ASSERT_DOUBLE_EQAULS(v3.length(), 1);

	return true;
}